package com.jhgk.gateway.config;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理
 *
 * @author zero
 */
@Order(Integer.MIN_VALUE)
@Component
@Slf4j
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {

    @Override
    public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) {
        int code = 500;
        ServerHttpResponse response = serverWebExchange.getResponse();
        ServerHttpRequest request = serverWebExchange.getRequest();
        log.error("当前请求 {} 请求类型 {}", request.getURI().getPath(), request.getMethod());
        if (throwable instanceof ResponseStatusException) {
            ResponseStatusException responseStatusException = (ResponseStatusException) throwable;
            code = responseStatusException.getStatus().value();
            response.setStatusCode(responseStatusException.getStatus());
        } else {
            response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            log.error("异常信息：", throwable);
        }
        Map<String, Object> map = new HashMap<>(3);
        map.put("code", code);
        map.put("msg", "请求失败");
        map.put("data", throwable.getMessage());
        DataBufferFactory bufferFactory = serverWebExchange.getResponse().bufferFactory();
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        return serverWebExchange.getResponse().writeWith(Flux.just(bufferFactory.wrap(JSONUtil.toJsonStr(map).getBytes())));
    }

}